using SG;
using UnityEngine;


public class AudioManager
{
    public enum eSoundType
    {
        BGM,         // 背景
        SceneEffect, // 场景音效
        Skill,       // 技能音效
        UI,          // 界面音效
        Dialog,      // 对话
        Speech,      // 场景演讲，（特殊用法 ）
        Cry,      // 不可替换的语音
    }
    public enum eAudioType
    {
        eAT_All = -1,  // 所有
        eAT_Backround,  //背景
        eAT_Scene,      //场景
        eAT_Skill,      //技能
        eAT_Shout,      //
        eAT_Monster,    //怪物
        eAT_UI,         //界面
        eAT_Dialog,     //对话
        eAT_Expression, //表情
        eAT_Story,      //剧情
        eAT_Guide,      //新手指引
        eAT_Speech,     // 场景演讲
        eAT_Cry,        // 角色特色语音
    }

    private static AudioManager inst = null;
    public static AudioManager Instance()
    {
        if (inst == null)
        {
            inst = new AudioManager();
        }
        return inst;
    }


    private GameObject sourceObj_Background = null;
    private GameObject SourceObj_Background
    {
        get
        {
            if (sourceObj_Background == null)
            {
                sourceObj_Background = new GameObject("SourceObj_Background");
                //sourceObj_Background.transform.parent = ObjectMgr.Instance().GetTempRoot();
                //sourceObj_Background.transform.localPosition = Vector3.zero;
                //float volume = LuaTools.Instance().GetGlobleFloat("GlobleFunc", "bgVolume");
                var item = sourceObj_Background.AddComponent<AudioGroup>();
                item.DoInit(eSoundType.BGM, 2);
                GameObject.DontDestroyOnLoad(sourceObj_Background);
            }
            return sourceObj_Background;
        }
    }

    private GameObject sourceObj_Other = null;
    private GameObject SourceObj_Other
    {
        get
        {
            if (sourceObj_Other == null)
            {
                sourceObj_Other = new GameObject("SourceObj_Other");
                sourceObj_Other.transform.parent = UIMgr.Instance().m_uiCamera2d.transform;
                sourceObj_Other.transform.localPosition = Vector3.zero;
                var item = sourceObj_Other.AddComponent<AudioGroup>();
                item.DoInit(eSoundType.BGM);
            }
            return sourceObj_Other;
        }
    }

    private GameObject sourceObj_Story = null;
    private GameObject SourceObj_Story
    {
        get
        {
            if (sourceObj_Story == null)
            {
                sourceObj_Story = new GameObject("SourceObj_Story");
                sourceObj_Story.transform.parent = UIMgr.Instance().m_uiCamera2d.transform;
                sourceObj_Story.transform.localPosition = Vector3.zero;
                var item = sourceObj_Background.AddComponent<AudioGroup>();
                item.DoInit(eSoundType.SceneEffect);
            }
            return sourceObj_Story;
        }
    }

    private GameObject sourceObj_Guide = null;
    private GameObject SourceObj_Guide
    {
        get
        {
            if (sourceObj_Guide == null)
            {
                sourceObj_Guide = new GameObject("SourceObj_Guide");
                sourceObj_Guide.transform.parent = UIMgr.Instance().m_uiCamera2d.transform;
                sourceObj_Guide.transform.localPosition = Vector3.zero;
                var item = sourceObj_Background.AddComponent<AudioGroup>();
                item.DoInit(eSoundType.Dialog);
            }
            return sourceObj_Guide;
        }
    }
    private GameObject sourceObj_Speech = null;
    private GameObject SourceObj_Speech
    {
        get
        {
            if (sourceObj_Speech == null)
            {
                sourceObj_Speech = new GameObject("SourceObj_Speech");
                sourceObj_Speech.transform.parent = UIMgr.Instance().m_uiCamera2d.transform;
                sourceObj_Speech.transform.localPosition = Vector3.zero;
                var item = sourceObj_Speech.AddComponent<AudioGroup>();
                item.DoInit(eSoundType.Speech);
            }
            return sourceObj_Speech;
        }
    }
    private GameObject sourceObj_Cry = null;
    private GameObject SourceObj_Cry
    {
        get
        {
            if (sourceObj_Cry == null)
            {
                sourceObj_Cry = new GameObject("SourceObj_Cry");
                sourceObj_Cry.transform.parent = UIMgr.Instance().m_uiCamera2d.transform;
                sourceObj_Cry.transform.localPosition = Vector3.zero;
                var item = sourceObj_Cry.AddComponent<AudioGroup>();
                item.DoInit(eSoundType.Cry);
            }
            return sourceObj_Cry;
        }
    }
    public string GetAudioFullName(string audioName, eAudioType audioType)
    {
        string audioPath = "";
        switch (audioType)
        {
            case eAudioType.eAT_Backround:
                audioPath = "Audio/Background/" + audioName;
                break;
            case eAudioType.eAT_Scene:
                audioPath = "Audio/Scene/" + audioName;
                break;
            case eAudioType.eAT_Skill:
                audioPath = "Audio/Skill/" + audioName;
                break;
            case eAudioType.eAT_Shout:
                audioPath = "Audio/Shout/" + audioName;
                break;
            case eAudioType.eAT_Monster:
                audioPath = "Audio/Monster/" + audioName;
                break;
            case eAudioType.eAT_UI:
                audioPath = "Audio/UI/" + audioName;
                break;
            case eAudioType.eAT_Dialog:
                audioPath = "Audio/Dialog/" + audioName;
                break;
            case eAudioType.eAT_Expression:
                audioPath = "Audio/expression/" + audioName;
                break;
            case eAudioType.eAT_Story:
                audioPath = "Audio/Story/" + audioName;
                break;
            case eAudioType.eAT_Guide:
                audioPath = "Audio/Guide/" + audioName;
                break;

        }
        return audioPath;
    }
    //private GameObject sourceObj_Background
    public int PlayAudio(ObjectBase sourceActor, string audioName, eAudioType audioType, bool isIgnoreTimeScale = false, bool isLoop = false)
    {
        if (string.IsNullOrEmpty(audioName))
        {
            return -1;
        }
        //获取音效路径
        var audioPath = GetAudioFullName(audioName, audioType);
        //加载音效
        AudioGroup audioSource = GetAudioGroup(sourceActor, audioType);
        switch (audioType)
        {
            case eAudioType.eAT_Backround:
                return audioSource.PlayAudio(audioPath, isLoop, false);
            case eAudioType.eAT_Skill:
                {
                    return audioSource.PlayAudio(audioPath, 1);
                }
            default:
                break;
        }

        return audioSource.PlayAudio(audioPath);
    }
    public int PlaySpeech(AudioClip clip, float f)
    {
        if (clip == null)
            return -1;
        AudioGroup audioSource = GetAudioGroup(null, eAudioType.eAT_Speech);
        if (audioSource)
            return audioSource.PlayAudio(clip, f * GetEffectVolume());
        return -1;
    }
    public void StopSpeech(int nIndex)
    {
        AudioGroup audioSource = GetAudioGroup(null, eAudioType.eAT_Speech);
        if (audioSource)
        {
            audioSource.StopAudio(nIndex);
        }
    }
    public int PlayCry(AudioClip clip, bool bBreak = false)
    {
        if (clip == null)
            return -1;
        AudioGroup audioSource = GetAudioGroup(null, eAudioType.eAT_Cry);
        if (audioSource)
            return audioSource.PlayAudioOnly(clip, GetEffectVolume(), bBreak);
        return -1;
    }
    public void FreshSpeech(int nIndex, float fScale)
    {
        AudioGroup audioSource = GetAudioGroup(null, eAudioType.eAT_Speech);
        if (audioSource)
        {
            audioSource.FreshVolume(nIndex, fScale * GetEffectVolume());
        }
    }
    public void PlayBGM(string sFile, string lFile)
    {
        AudioGroup audioSource = GetAudioGroup(null, eAudioType.eAT_Backround);
        sFile = GetAudioFullName(sFile, eAudioType.eAT_Backround);
        lFile = GetAudioFullName(lFile, eAudioType.eAT_Backround);
        if (audioSource)
        {
            audioSource.PlayBGM(sFile, lFile);
        }
    }

    public int PlayAudio(ObjectBase sourceActor, AudioClip clip, eAudioType audioType, bool isIgnoreTimeScale = false, bool isLoop = false)
    {
        if (clip == null)
            return -1;
        //加载音效
        AudioGroup audioSource = GetAudioGroup(sourceActor, audioType);
        switch (audioType)
        {
            case eAudioType.eAT_Backround:
                return audioSource.PlayAudio(clip, isLoop, false);
            case eAudioType.eAT_Skill:
                {
                    return audioSource.PlayAudio(clip, 1);
                }
            default:
                break;
        }
        return audioSource.PlayAudio(clip);
    }
    public int PlayAudioOneShot(ObjectBase sourceActor, AudioClip clip, eAudioType audioType, bool isIgnoreTimeScale = false, bool isLoop = false)
    {
        if (clip == null) return -1;


        //加载音效
        AudioGroup audioSource = GetAudioGroup(sourceActor, audioType);
        switch (audioType)
        {
            case eAudioType.eAT_Skill:
                {
                    return audioSource.PlayAudioOneShot(clip, 1);
                }
            default:
                break;
        }
        return audioSource.PlayAudioOneShot(clip, 1);
    }
    public bool CheckAudioIsPlaying(ObjectBase sourceActor, eAudioType audioType, int nIndex)//只适用于BGM
    {
        AudioGroup audioGroup = GetAudioGroup(sourceActor, audioType);
        return audioGroup.IsPlaying(nIndex);
    }

    public float GetAuidoTime(ObjectBase sourceActor, eAudioType audioType, int nIndex)
    {
        AudioGroup audioGroup = GetAudioGroup(sourceActor, audioType);
        return audioGroup.GetClipTime(nIndex);
    }

    public AudioGroup GetAudioGroup(ObjectBase sourceActor, eAudioType audioType)
    {
        AudioGroup audioSource = null;
        //获取音效载体
        if (audioType == eAudioType.eAT_Dialog)
        {
            if (sourceActor)
                audioSource = sourceActor.GetAudioSource();
        }
        else if (audioType == eAudioType.eAT_Backround)
        {
            audioSource = SourceObj_Background.GetComponent<AudioGroup>();

        }
        else if (audioType == eAudioType.eAT_Story)
        {
            audioSource = SourceObj_Story.GetComponent<AudioGroup>();
        }
        else if (audioType == eAudioType.eAT_Guide || audioType == eAudioType.eAT_UI)
        {
            audioSource = SourceObj_Guide.GetComponent<AudioGroup>();
        }
        else if (audioType == eAudioType.eAT_Speech)
        {
            audioSource = SourceObj_Speech.GetComponent<AudioGroup>();
        }
        else if (audioType == eAudioType.eAT_Cry)
        {
            audioSource = SourceObj_Cry.GetComponent<AudioGroup>();
        }
        else if (sourceActor != null)
        {
            audioSource = sourceActor.GetAudioSource();
        }

        else
        {
            audioSource = SourceObj_Other.GetComponent<AudioGroup>();
            audioSource.To3D();
        }
        return audioSource;
    }


    public void PauseAudioPlay(ObjectBase sourceActor, eAudioType audioType, int nIndex, bool isPause = true)
    {
        AudioGroup audioSource = GetAudioGroup(sourceActor, audioType);
        if (isPause)
        {
            audioSource.PauseAudio(nIndex, isPause);
        }
    }

    public void PauseAllAudio(ObjectBase sourceActor, eAudioType audioType, bool isPause = true)
    {
        AudioGroup audioSource = GetAudioGroup(sourceActor, audioType);
        if (isPause)
        {
            audioSource.PauseAllAudio(isPause);
        }
    }
    public void StopAudioPlay(ObjectBase sourceActor, eAudioType audioType, int nIndex)
    {
        AudioGroup audioSource = GetAudioGroup(sourceActor, audioType);
        audioSource.StopAudio(nIndex);
    }

    public void StopAllAudioPlay(ObjectBase sourceActor, eAudioType audioType, int nIndex)
    {
        AudioGroup audioSource = GetAudioGroup(sourceActor, audioType);
        audioSource.StopAllAudio();
    }


    // 播放外部传进来的声音,用来播放麦克采集的或者网络发送的声音
    public void PlayAudio(AudioClip clip)
    {
        var audio = SourceObj_Other.GetComponent<AudioGroup>();
        if (audio != null)
            audio.PlayClip(clip);
    }


    #region 新接口

    public void SetVolumeChange(int num, eAudioType type)
    {
        switch (type)
        {
            case eAudioType.eAT_All:
                SetVolumePercent();
                break;
            case eAudioType.eAT_Backround:
                SetBGMVolume();
                break;
            case eAudioType.eAT_Skill:
                SetEffectVolume();
                break;
        }
    }

    public int GetVolumeChange(eAudioType type)
    {
        switch (type)
        {
            case eAudioType.eAT_All:
                return SG.GameSettingManager.Instance().GetVolume(SG.VolumeType.Main);
            case eAudioType.eAT_Backround:
                return SG.GameSettingManager.Instance().GetVolume(SG.VolumeType.Music);
            case eAudioType.eAT_Skill:
                return (int)(SG.GameSettingManager.Instance().GetVolume(SG.VolumeType.Effect));
            default:
                return 0;
        }
    }

    public float GetVolume(eSoundType type)
    {
        switch (type)
        {
            case eSoundType.BGM:
                return GetBGMVolume();
            case eSoundType.Dialog:
                return GetEffectVolume();
            case eSoundType.SceneEffect:
                return GetEffectVolume();
            case eSoundType.Skill:
            case eSoundType.Cry:
            case eSoundType.Speech:
                return GetEffectVolume();
            case eSoundType.UI:
                return GetEffectVolume();
        }
        return 0;
    }


    public void SetVolumePercent()
    {
        SetBGMVolume();
        SetEffectVolume();
    }

    public int GetVolumePercent()
    {
        return SG.GameSettingManager.Instance().GetVolume(SG.VolumeType.Main);
    }

    public void SetBGMVolume()
    {
        float volume = GetBGMVolume();
        SetVolume(volume, null, eAudioType.eAT_Backround);

        SG.AudioSourceFade[] audios = GameObject.FindObjectsOfType<SG.AudioSourceFade>();
        foreach (var audio in audios)
        {
            audio.SetVolume();
        }
    }
    public float GetBGMVolume()
    {
        return GetVolumePercent() * GetVolumeChange(eAudioType.eAT_Backround) * TypeDefine.CommonScale;
    }

    public void SetEffectVolume()
    {
        SetVolume(GetEffectVolume(), null, eAudioType.eAT_Skill);
        SetVolume(GetEffectVolume(), null, eAudioType.eAT_Scene);
        SetVolume(GetEffectVolume(), null, eAudioType.eAT_Dialog);
        SetVolume(GetEffectVolume(), null, eAudioType.eAT_Story);
        SetVolume(GetEffectVolume(), null, eAudioType.eAT_UI);
        SetVolume(GetEffectVolume(), null, eAudioType.eAT_Speech);
    }
    public float GetEffectVolume()
    {
        return GetVolumePercent() * GetVolumeChange(eAudioType.eAT_Skill) * TypeDefine.CommonScale;
    }


    // 设置静音
    public void SetMute(bool bMute, ObjectBase sourceActor, eAudioType audioType = eAudioType.eAT_All)
    {
        AudioGroup audioSource = GetAudioGroup(sourceActor, audioType);
        if (audioSource != null)
        {
            audioSource.SetAudioMute(bMute);
        }
    }
    // 设置音量
    public void SetVolume(float fVolume, ObjectBase sourceActor, eAudioType audioType = eAudioType.eAT_All)
    {
        AudioGroup audioSource = GetAudioGroup(sourceActor, audioType);
        if (audioSource != null)
        {
            audioSource.SetAudioVolume(fVolume);
        }
    }

    // 播放背景音乐

    int m_nCurBGM = 0;
    int m_nCurInsertBGM = 1;
    string m_strCurBGM;
    public void PlayBGM(string fileName, float timeHandOver = 0)
    {
        // 如果已经正在播放，不播了
        if (m_strCurBGM == fileName)
        {
            return;
        }
        AudioGroup audioSource = GetAudioGroup(null, eAudioType.eAT_Backround);
        if (audioSource)
        {
            audioSource.PlayAudioDelay(m_nCurBGM, fileName, true, timeHandOver);
            m_strCurBGM = fileName;
        }

    }
    // 停止当前背景音乐
    public void StopBGM()
    {
        AudioGroup audioSource = GetAudioGroup(null, eAudioType.eAT_Backround);
        if (audioSource)
        {
            audioSource.StopAudio(m_nCurBGM);
            m_strCurBGM = "";
        }
    }
    // 插入背景音乐，这个播放完，就继续播放以前的
    public void InsertBGM(string fileName, float timeHandOver = 0)
    {
        // 用新的音轨来播放插入的
        AudioGroup audioSource = GetAudioGroup(null, eAudioType.eAT_Backround);
        if (audioSource)
        {
            fileName = GetAudioFullName(fileName, eAudioType.eAT_Backround);
            audioSource.PlayAudio(m_nCurInsertBGM, fileName, false);
        }
    }
    //  继续播放背景音乐
    public void ContinueBGM()
    {
        AudioGroup audioSource = GetAudioGroup(null, eAudioType.eAT_Backround);
        if (audioSource)
        {
            audioSource.StopAudio(m_nCurInsertBGM);
            audioSource.PlayAudio(m_nCurBGM);
        }
    }
    #endregion
}